package com.dxy.hms.socketio;

import cn.hutool.core.collection.CollUtil;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.PingListener;
import com.corundumstudio.socketio.listener.PongListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;

@Slf4j
@Component
public class ServerStartupService implements IServerStartupService {

    @Autowired
    private SocketIOServer socketIOServer;
    @Autowired
    private ISessionService sessionService;
    @Autowired(required = false)
    private List<OnConnectEventHandler> onConnectEventHandlers;
    @Autowired(required = false)
    private List<OnDisconnectEventHandler> onDisconnectEventHandlers;
    @Autowired(required = false)
    private List<OnMessageEventHandler> onMessageEventHandlers;

    @PostConstruct
    public void init(){
        start();
    }

    @PreDestroy
    public void destroy(){
        stop();
    }

    @Override
    public void start() {
        // 监听客户端连接
        socketIOServer.addConnectListener(socketIOClient -> {
            log.debug("客户端： {} 已连接", socketIOClient.getRemoteAddress().toString());
            ISession session = new SocketIoSession(socketIOClient);
            sessionService.addSession(session);
            if (CollUtil.isNotEmpty(onConnectEventHandlers)){
                onConnectEventHandlers.forEach(handler -> handler.onConnect(session));
            }
        });

        // 监听客户端断开连接
        socketIOServer.addDisconnectListener(socketIOClient -> {
            log.debug("客户端： {} 已断开", socketIOClient.getRemoteAddress().toString());
            ISession session = sessionService.getSessionById(socketIOClient.getSessionId().toString());
            sessionService.removeSession(session);
            if (CollUtil.isNotEmpty(onDisconnectEventHandlers)){
                onDisconnectEventHandlers.forEach(handler -> handler.onDisconnect(session));
            }
        });

        // 只是测试看看（使用socketio的好处是内部集成的心跳检测，不用再自己封装）
        socketIOServer.addPingListener(socketIOClient -> log.debug(socketIOClient.getRemoteAddress().toString()+"ping..."));
        socketIOServer.addPongListener(socketIOClient -> log.debug(socketIOClient.getRemoteAddress().toString()+"pong..."));

        // 监听自定义事件
        // socketIOServer.addEventListener("test_event", Message.class, (socketIOClient, message, ackRequest) -> log.debug("收到消息：{}",message));
        if (CollUtil.isNotEmpty(onMessageEventHandlers)){
            onMessageEventHandlers.forEach(handler -> {
                socketIOServer.addEventListener(handler.getEvent(), handler.getDataClass(), (socketIOClient, message, ackRequest) -> {
                    log.debug("收到消息：{}",message);
                    handler.onMessage(socketIOClient, message, ackRequest);
                });
            });
        }

        // 启动socket服务
        socketIOServer.start();
    }

    @Override
    public void stop() {
        if (socketIOServer != null) {
            socketIOServer.stop();
            socketIOServer = null;
        }
    }

}
